package com.me.study.javaCore.reflection;

import com.me.study.javaCore.enumm.BaseEnum;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * 反射获取 class对象
 */
public class ClassReflectTests {

    @Test
    public void lambdaClass() {
        Runnable lambda = () -> System.out.println("啥都不干的 Runnable");
        System.out.println(lambda.getClass());

        LambdaClass.printLambdaClassName(lambda);
    }

    public static class LambdaClass {
        public static void printLambdaClassName(Runnable target) {
            System.out.println("Lambda 类名:");
            System.out.println(target.getClass());
        }
    }

    @Test
    public void isAssignableFrom() {
        assertTrue("Object.class 是 ClassReflectTests.class 的超类", Object.class.isAssignableFrom(ClassReflectTests.class));
        assertTrue("ClassReflectTests.class 和 ClassReflectTests.class 相同",
                ClassReflectTests.class.isAssignableFrom(ClassReflectTests.class));
    }

    @Test
    public void isInstance() {
        ClassReflectTests instance = new ClassReflectTests();
        assertTrue("instance 是 Object.class 的子实例", Object.class.isInstance(instance));
        assertTrue("instance 是 ClassReflectTests.class 的实例", ClassReflectTests.class.isInstance(instance));
    }

    /**
     * 静态内部类 需要用  `package.外部类名$内部类名`
     */
    @Test
    public void testStaticInnerClass() {
        try {
            Class<?> clazz = Class.forName("com.me.study.javaCore.reflection.ClassReflectTests$StaticInnerClass");
            assertEquals("com.me.study.javaCore.reflection.ClassReflectTests$StaticInnerClass", clazz.getName());
            assertEquals("SimpleName 只有自己的类名", "StaticInnerClass", clazz.getSimpleName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 成员内部类 需要用  `package.外部类名$内部类名`
     */
    @Test
    public void testInnerClass() {
        try {
            Class<?> clazz = Class.forName("com.me.study.javaCore.reflection.ClassReflectTests$InnerClass");
            assertEquals("com.me.study.javaCore.reflection.ClassReflectTests$InnerClass", clazz.getName());
            assertEquals("SimpleName 只有自己的类名", "InnerClass", clazz.getSimpleName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testEnum() {
        try {
            Class<?> clazz = Class.forName("com.me.study.javaCore.enumm.ColorEnum");
            if (BaseEnum.class.isAssignableFrom(clazz)) {
                BaseEnum[] enumConstants = ((Class<BaseEnum>) clazz).getEnumConstants();
                for (BaseEnum obj : enumConstants) {
                    // System.out.println(((Enum) obj).name() + ": " + obj.getCode() + ", " + obj.getDesc());
                    System.out.println(obj.toString() + ": " + obj.getCode() + ", " + obj.getDesc());
                }
            }
            else {
                throw new RuntimeException("枚举类型解析失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static class StaticInnerClass {
    }

    public static class InnerClass {
    }

}
